const Queue = require("bull");
const Redis = require("ioredis");
const _ = require("lodash");
const fs = require("fs");

/**
 * 加载任务
 * @param {*} app
 */
function loadTask(app) {
  loadService(app);
  if (!app.config.redis) {
    app.log.warn("config[redis] undefined, task loading failed", true);
  } else {
    const config = getRedisConfig(app);
    const key = config.redis.taskKey || "adminTask";
    const task = new Queue(key, config);
    app.task = task;
    //判断mysql是否开启
    if (app.orm) app.service.Task.init(app);
  }
}
//加载队列
function loadQueue(app) {
  if (!app.config.redis) {
    app.log.warn("config[redis] undefined, queue loading failed", true);
  } else {
    const config = getRedisConfig(app);
    const filePath = __dirname + "/../../../queue/";
    const fileExists = fs.existsSync(filePath);
    if (!fileExists) return;
    app.queue = {};
    //加载文件
    require("young-require-all")({
      dirname: filePath,
      filter: /(.+)\.ts$/,
      resolve: function (Service) {
        for (let ServiceName in Service) {
          const name = Service[ServiceName].name;
          app.queue[name] = new Queue(name, config);
          app.log.info(
            `queue [${name}] loaded successfully, usage: this.app.queue.${name}`,
            true
          );
          app.queue[name].process(async (job, done) => {
            const queueClass = new Service[ServiceName](app);
            return queueClass.execute(job, done);
          });
        }
      },
    });
  }
}
function getRedisConfig(app) {
  if (app.config.redis.cluster) {
    const opts = {
      createClient: function () {
        return new Redis.Cluster(app.config.redis.cluster);
      },
      prefix: `{young}`,
      settings: {
        lockDuration: 30000,
        stalledInterval: 30000,
        maxStalledCount: 1,
        guardInterval: 5000,
        retryProcessDelay: 5000,
        drainDelay: 1,
        backoffStrategies: {},
        lockRenewTime: 15000,
      },
    };
    return opts;
  } else {
    return { redis: app.config.redis };
  }
}
function loadService(app) {
  if (_.isEmpty(app.service)) {
    const fileBase = __dirname + "/../../../";
    require("young-require-all")({
      dirname: fileBase + "module",
      filter: /(.+)\.ts$/,
      resolve: function (Service) {
        for (let ServiceName in Service) {
          let name = Service[ServiceName].name;
          app.service[name] = new Service[ServiceName](app);
        }
      },
    });
  }
}
//消费
function consume(app) {
  if (app.task) {
    app.task.process(async (job, done) => {
      app.service.Task.execute(job, done);
    });
  }
}
module.exports = { loadTask, loadQueue, consume };
